#ifndef GEOMETRY_H
#define GEOMETRY_H

#include "Object.h"
#include "Ray.h"
#include "Pigment.h"
#include "Finish.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "AABB.h"
#include "Texture2.h"

#define T_SPHERE 0
#define T_PLANE 1
#define T_BOX 2
#define T_TRIANGLE 3
#define T_CONE 4

#ifndef PI
#define PI 3.1415926535
#endif

using namespace glm;

struct AABB;

class Geometry: public Object {
public:
    MFinish finish;
    MPigment pigment;
    mat4 transform;
    mat4 vtrans;
    string name;
    bool light;
    NoiseGen *noise;

    Geometry() {
        transform = mat4(1.0);
        vtrans = mat4(1.0);
        oType = GEOMETRY_TYPE;
    }

    void setNoise(NoiseGen *n) {
        noise = n;
    }

    virtual Symbol parse(ifstream &file, Symbol curToken) {};
    virtual bool intersect(Ray *r) {};
    virtual vec3 getNormal(Ray *r) {};
    virtual void print() {
        printf("\tTransform:\n\t%f\t%f\t%f\t%f\n\t%f\t%f\t%f\t%f\n\t"
        "%f\t%f\t%f\t%f\n\t%f\t%f\t%f\t%f\n",
        transform[0][0], transform[1][0],
        transform[2][0], transform[3][0],
        transform[0][1], transform[1][1],
        transform[2][1], transform[3][1],
        transform[0][2], transform[1][2],
        transform[2][2], transform[3][2],
        transform[0][3], transform[1][3],
        transform[2][3], transform[3][3]);

        finish.print();
        pigment.print();
    }

    virtual AABB *generateAABB() {};
    virtual int type() {};
    virtual vec3 genRandomPoint(vec3 look, int cur, int lim) {};
};



extern Symbol parseTranslate(ifstream &file, Symbol curToken, mat4 *trans);
extern Symbol parseRotate(ifstream &file, Symbol curToken, mat4 *trans); 
extern Symbol parseScale(ifstream &file, Symbol curToken, mat4 *trans);
extern Symbol parseMaterials(ifstream &file, Symbol curToken, Geometry *g); 
extern void fix_AABB_transform(AABB *b, mat4 transform);


#endif
